home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / unix / ls_4_0k / part03 < prev    next >
Encoding:
Internet Message Format  |  1990-07-03  |  37.4 KB

  1. Path: xanth!cs.odu.edu!Amiga-Request
  2. From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v90i197: ls 4.0k - yet another unix-like ls command, Part03/04
  5. Message-ID: <13041@xanth.cs.odu.edu>
  6. Date: 3 Jul 90 19:25:00 GMT
  7. Sender: tadguy@cs.odu.edu
  8. Reply-To: kim@uts.amdahl.com (Kim E. DeVaughn)
  9. Lines: 1358
  10. Approved: tadguy@cs.odu.edu (Tad Guy)
  11. X-Mail-Submissions-To: Amiga@cs.odu.edu
  12. X-Post-Discussions-To: comp.sys.amiga
  13.  
  14. Submitted-by: kim@uts.amdahl.com (Kim E. DeVaughn)
  15. Posting-number: Volume 90, Issue 197
  16. Archive-name: unix/ls-4.0k/part03
  17.  
  18. #!/bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 3 (of 4)."
  25. # Contents:  src/lssup.a
  26. # Wrapped by tadguy@xanth on Tue Jul  3 15:22:13 1990
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'src/lssup.a' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'src/lssup.a'\"
  30. else
  31. echo shar: Extracting \"'src/lssup.a'\" \(34948 characters\)
  32. sed "s/^X//" >'src/lssup.a' <<'END_OF_FILE'
  33. X* --------------------------------------------------------------------- *
  34. X* lssup.a - Assembly support routines for ls.c
  35. X* Written by Justin V. McCormick 89-07-24
  36. X* Modified for use in v4.0k by Kim E. DeVaughn - 05/11/90
  37. X* --------------------------------------------------------------------- *
  38. X    IFD    CAPE
  39. X    CSYMFMT
  40. X    BASEREG B
  41. X    SMALLOBJ
  42. X    ADDSYM
  43. X    OPTIMON
  44. X    IDNT    "lssup.a"
  45. X    ENDC
  46. X
  47. X
  48. XSYS    MACRO    *
  49. X    IFGT    NARG-2
  50. X    FAIL    !!!
  51. X    ENDC
  52. X    IFEQ    NARG-2
  53. X    MOVE.L    \2,a6
  54. X    ENDC
  55. X    JSR    LVO\1(a6)
  56. X    ENDM
  57. X
  58. XXLVO    MACRO    *
  59. X    XREF    LVO\1
  60. X    ENDM
  61. X
  62. X; Equates
  63. Xfib_DiskKey        EQU    $0
  64. Xfib_DirEntryType    EQU    $4
  65. Xfib_FileName        EQU     $8
  66. Xfib_Size        EQU     $7C
  67. Xfib_NumBlocks        EQU     $80
  68. Xfib_DateStamp        EQU     $84
  69. Xfib_SIZEOF        EQU     $104
  70. X
  71. Xds_Days         EQU     $0
  72. Xds_Minute        EQU     $4
  73. Xds_Tick         EQU     $8
  74. X
  75. XLH_HEAD         EQU     $0
  76. XLN_PRED         EQU     $4
  77. XLN_SUCC         EQU     $0
  78. X
  79. Xfe_Node         EQU     $0
  80. Xfe_Fib            EQU     $8
  81. X
  82. Xpr_ConsoleTask        EQU     $A4
  83. X
  84. XMEMF_CLEAR        EQU     $10000
  85. Xsp_Msg            EQU     $0
  86. Xsp_Pkt            EQU     $14
  87. Xsp_SIZEOF        EQU     $44
  88. Xdp_Link         EQU     $0
  89. Xdp_Port         EQU     $4
  90. Xdp_Arg1         EQU     $14
  91. Xdp_Type         EQU     $8
  92. XACTION_SCREEN_MODE  EQU     $3E2
  93. XLN_NAME         EQU     $A
  94. XLN_PRI            EQU     $9
  95. XLN_TYPE         EQU     $8
  96. XMP_FLAGS        EQU     $E
  97. XMP_MSGLIST        EQU     $14
  98. XMP_SIGBIT        EQU     $F
  99. XMP_SIGTASK        EQU     $10
  100. XMP_SIZE         EQU     $22
  101. XNT_MSGPORT        EQU     $4
  102. XPA_SIGNAL        EQU     $0
  103. X
  104. X* Library offsets
  105. X    XLVO    AddPort
  106. X    XLVO    AddTail
  107. X    XLVO    AllocMem
  108. X    XLVO    AllocSignal
  109. X    XLVO    CopyMem
  110. X    XLVO    Debug
  111. X    XLVO    Examine
  112. X    XLVO    FindTask
  113. X    XLVO    FreeMem
  114. X    XLVO    FreeSignal
  115. X    XLVO    GetMsg
  116. X    XLVO    Input
  117. X    XLVO    Insert
  118. X    XLVO    IsInteractive
  119. X    XLVO    Output
  120. X    XLVO    ParentDir
  121. X    XLVO    PutMsg
  122. X    XLVO    RawDoFmt
  123. X    XLVO    Read
  124. X    XLVO    RemPort
  125. X    XLVO    WaitForChar
  126. X    XLVO    WaitPort
  127. X    XLVO    Write
  128. X    XLVO    UnLock
  129. X
  130. X* External constants
  131. X    XREF    @AllocFib
  132. X    XREF    @stpcpy
  133. X    XREF    @strcat
  134. X    XREF    @strlen
  135. X    XREF    baddatestr
  136. X    XREF    badtimestr
  137. X    XREF    ColonStr
  138. X    XREF    datepat
  139. X    XREF    dayspermonth
  140. X    XREF    DOSBase
  141. X    XREF    gwbrstr
  142. X    XREF    LSFlags
  143. X    XREF    RamNameStr
  144. X    XREF    SlashStr
  145. X    XREF    sortkey
  146. X    XREF    timepat
  147. X
  148. X    SECTION CODE
  149. X* --------------------------------------------------------------------- *
  150. X* VOID *myalloc (LONG)
  151. X*   d0          d0
  152. X* --------------------------------------------------------------------- *
  153. X    XDEF    @myalloc
  154. X@myalloc:
  155. X    movem.l d2/a6,-(sp)
  156. X    addq.l    #4,d0            ;Include sizeof(LONG)
  157. X    move.l    d0,d2            ;Copy to survive AllocMem
  158. X    moveq    #0,d1            ;MEMF_ANYTHING
  159. X    SYS    AllocMem,4        ;AllocMem(size + 4, 0L)
  160. X    tst.l    d0            ;Got it?
  161. X     beq.s    1$
  162. X    movea.l d0,a6            ;Copy pointer
  163. X    move.l    d2,(a6)+                ;Stash size in first 4 bytes
  164. X    move.l    a6,d0            ;return final pointer in d0
  165. X1$
  166. X    movem.l (sp)+,d2/a6
  167. X    rts
  168. X
  169. X* --------------------------------------------------------------------- *
  170. X* VOID myfree (VOID *)
  171. X*        a0
  172. X* --------------------------------------------------------------------- *
  173. X    XDEF    @myfree
  174. X@myfree:
  175. X    move.l    a6,-(sp)
  176. X
  177. X    lea    -4(a0),a1               ;Put in sys reg
  178. X    move.l    (a1),d0                 ;d0 = size to free
  179. X    SYS    FreeMem,4
  180. X
  181. X    movea.l (sp)+,a6
  182. X    rts
  183. X
  184. X* --------------------------------------------------------------------- *
  185. X* void asprintf(wstr, formatstring, args)
  186. X*   char *wstr;
  187. X*   char *formatstring;
  188. X*   char **args;
  189. X*
  190. X* Synopsis: Given formatstring and args to format, formats output to wstr.
  191. X* Similar to sprintf(), except doesn't handle floats.
  192. X* --------------------------------------------------------------------- *
  193. X    XDEF    asprintf
  194. Xasprintf:
  195. X    link    a5,#0
  196. X    movem.l d0-d2/a0-a3/a6,-(sp)    ;Save everything we might clobber
  197. X
  198. X* Call format function to convert fmtstring and args to buffer on the stack
  199. X    movea.l 12(a5),a0               ;Grab format string
  200. X    lea    16(a5),a1               ;Grab EA of arguments
  201. X    lea    kput1,a2        ;Grab EA of output subroutine
  202. X    movea.l 8(a5),a3                ;Grab EA of dest workspace
  203. X    SYS    RawDoFmt,4        ;Format it into workspace
  204. X
  205. X    movem.l (sp)+,d0-d2/a0-a3/a6    ;Restore registers
  206. X    unlk    a5            ;And stack frame
  207. X    rts
  208. X
  209. X* --------------------------------------------------------------------- *
  210. X* RawDoFmt() output routine for xprintf, called for each formatted char.
  211. X* Takes byte in d0 and puts in buffer pointed to by a3, then increments a3.
  212. X* --------------------------------------------------------------------- *
  213. X    XDEF    kput1
  214. Xkput1:
  215. X    move.b    d0,(a3)+
  216. X    rts
  217. X
  218. X* --------------------------------------------------------------------- *
  219. X* void GetWinBounds(width, height)
  220. X*   long *width, *height;
  221. X*       a0        a1
  222. X* Find current console window, determine width and height
  223. X* in terms of current font, update width and height VPARMS passed.
  224. X* --------------------------------------------------------------------- *
  225. Xheight    EQU    -4
  226. Xwidth    EQU    -8
  227. Xconid    EQU    -12
  228. Xpacket    EQU    -16
  229. Xrpport    EQU    -20
  230. Xrpstr    EQU    -40
  231. X
  232. X    XDEF    @GetWinBounds
  233. X@GetWinBounds:
  234. X    link    a5,#-44
  235. X    movem.l d2-d4/a2/a6,-(sp)
  236. X
  237. X    move.l    a0,width(a5)            ;Save width/height pointers on stack
  238. X    move.l    a1,height(a5)
  239. X
  240. X    SYS    Input,DOSBase(a4)       ;Grab Input filehandle
  241. X    move.l    d0,d1
  242. X    SYS    IsInteractive        ;IsInteractive(Input())?
  243. X    tst.l    d0
  244. X     beq.s    gwbnowbrep        ;Nope, can't get a bounds report
  245. X    SYS    Output
  246. X    move.l    d0,d1
  247. X    SYS    IsInteractive        ;IsInteractive(Output())?
  248. X    tst.l    d0
  249. X     beq.s    gwbnowbrep        ;Nope, don't clutter output stream
  250. X
  251. X    suba.l    a1,a1
  252. X    SYS    FindTask,4        ;d0 = FindTask(0L), our process
  253. X    movea.l d0,a0            ;Transfer to address reg
  254. X    move.l    pr_ConsoleTask(a0),conid(a5) ;Save proc->pr_ConsoleTask
  255. X    tst.l    conid(a5)               ;Is there really a console there?
  256. X     bne.s    gwbgotcon        ;Yep
  257. X
  258. Xgwbnowbrep:
  259. X* Else we cannot get a window bounds report from this source
  260. X    moveq    #23,d1            ;return H=23
  261. X    moveq    #77,d2            ;    W=77
  262. X    bra    gwbupdate
  263. X
  264. Xgwbgotcon:
  265. X    moveq    #0,d4            ;Clear our success status register
  266. X
  267. X    moveq    #0,d0
  268. X    movea.l d0,a0
  269. X    jsr    CreatePort
  270. X    move.l    d0,rpport(a5)           ;rpport = CreatePort(0L, 0L)
  271. X     beq    gwbdone         ;Oops, no signals or ram available!
  272. X    moveq    #sp_SIZEOF,d0
  273. X    jsr    @myalloc
  274. X    move.l    d0,packet(a5)           ;packet = AllocBlock(sizeof(*packet))
  275. X     beq    gwbfreeport        ;Oops, no ram, free up port
  276. X
  277. X* Okay, we got our process id, reply port, and packet
  278. X* Now toggle the console into raw mode
  279. X    movea.l rpport(a5),a2
  280. X    movea.l d0,a1
  281. X    movea.l conid(a5),a0
  282. X    moveq    #1,d0
  283. X    jsr    SetConsoleType        ;SetConsoleType(1L, conid, packet, rpport)
  284. X
  285. X* Request a window bounds report
  286. X    SYS    Output,DOSBase(a4)
  287. X    move.l    d0,d1
  288. X    moveq    #4,d3
  289. X    lea    gwbrstr(a4),a0
  290. X    move.l    a0,d2
  291. X    SYS    Write,DOSBase(a4)       ;Write(Output(), "\2330 q", 4L);
  292. X    cmpi.l    #$0004,d0        ;Did the console choke on it?
  293. X     bne    gwbsetcook        ;hmmm, see if we can back out gracefully
  294. X
  295. X* Read the report string into stack buffer, if there is one
  296. X    move.l    #10000,d2
  297. X    SYS    Input
  298. X    move.l    d0,d1
  299. X    SYS    WaitForChar        ;WaitForChar(Input(), 10000L) (.01 secs)
  300. X    tst.l    d0            ;Did we get the report?
  301. X     beq    gwbsetcook        ;Nope, must not be a report coming
  302. X
  303. X    SYS    Input
  304. X    move.l    d0,d1
  305. X    moveq    #16,d3            ;Don't let it get longer than 16 characters
  306. X    lea    rpstr(a5),a0            ;Point to input string area
  307. X    move.l    a0,d2
  308. X    SYS    Read            ;Read(Input(), rpstr, 16L)
  309. X    move.l    d0,d4            ;Save read length while we close shop
  310. X
  311. X* Turn the console back to cooked mode pronto to avoid cursor blink
  312. Xgwbsetcook:
  313. X    movea.l rpport(a5),a2
  314. X    movea.l packet(a5),a1
  315. X    movea.l conid(a5),a0
  316. X    moveq    #0,d0
  317. X    jsr    SetConsoleType        ;SetConsoleType(0L, conid, packet, rpport)
  318. X
  319. X* Release resources we borrowed
  320. Xgwbfreepack:
  321. X    move.l    packet(a5),d0           ;Did we allocate a packet?
  322. X     beq.s    gwbfreeport        ;nay, check for port to free
  323. X    movea.l d0,a0
  324. X    jsr    @myfree         ;Else FreeBlock(packet)
  325. X
  326. Xgwbfreeport:
  327. X    move.l    rpport(a5),d0           ;if (rpport)...
  328. X     beq    gwbdone         ;nope
  329. X    jsr    DeletePort        ;Else DeletePort(rpport)
  330. X
  331. X* Finally, sanity check window bounds report string
  332. X* d4 = length of report string according to Read()
  333. X    cmpi.l    #9,d4            ;Less than 8 characters returned?
  334. X     ble    gwbdone         ;hmmm, phonky bounds report from DOS?
  335. X    lea    rpstr(a5),a2            ;a2 = rpstr
  336. X    cmpi.b    #';',4(a2)              ;Matches a typical report template?
  337. X     bne    gwbdone         ;nope, got some weird junk back?
  338. X    cmpi.b    #'r',-1(a2,d4.w)        ;Last byte is 'r' for report?
  339. X     bne    gwbdone         ;Nope, message fubar!
  340. X
  341. X* Parse the height and width variables from the field now
  342. X* Our report format looks like this in hex:
  343. X*    9b 31 3b 31 3b y2 y1 3b x2 x1 20 72
  344. X* Or in ascii:
  345. X*    <0x9b>1;1;20;77 r
  346. X* Which would indicate a width of 77 cols and a height of 20 rows for
  347. X* the current console device
  348. X*
  349. X* REGS: a2 points to beginning of 'r' terminated string
  350. X
  351. X    addq.w    #5,a2            ;Point to first char of Y size
  352. X    moveq    #0,d1            ;Clear out work reg
  353. X
  354. X* Convert ascii rows value to LONG, update host data
  355. X    move.b    (a2)+,d1                ;Grab a Y
  356. X    subi.w    #'0',d1                 ;Less ascii offset
  357. X    cmpi.b    #';',(a2)               ;Any more Y digits?
  358. X     beq.s    1$            ;Nope
  359. X    mulu    #10,d1            ;Else shift by 10
  360. X    add.b    (a2)+,d1                ;Add least significant Y digit
  361. X    subi.b    #'0',d1                 ;Less ascii offset
  362. X    cmpi.b    #';',(a2)               ;Any more Y digits?
  363. X     beq.s    1$            ;Nope
  364. X    mulu    #$000a,d1        ;Else shift by 10
  365. X    add.b    (a2)+,d1                ;Add least significant Y digit
  366. X    subi.b    #'0',d1                 ;Less ascii offset
  367. X                    ;We'll assume screen height < 999 rows
  368. X1$
  369. X* Convert ascii columns value to LONG, update host data
  370. X    addq.w    #1,a2            ;Move past the ';' separator
  371. X    moveq    #0,d2            ;Zap work reg
  372. X    move.b    (a2)+,d2                ;Grab msd of X
  373. X    cmpi.b    #' ',d2                 ;Premature end?
  374. X     beq    gwbdone         ;Huh, must be garbage - don't update VPARMS
  375. X    cmpi.b    #';',d2                 ;Also a possible error
  376. X     beq    gwbdone
  377. X    cmpi.b    #'r',d2                 ;And what about this?
  378. X     beq    gwbdone
  379. X
  380. X    subi.b    #'0',d2                 ;Okay, adjust ascii offset
  381. X    cmpi.b    #' ',(a2)               ;Hit end of report?
  382. X     beq.s    2$            ;Yep
  383. X    mulu    #$000a,d2        ;Else shift by 10
  384. X    add.b    (a2)+,d2                ;Add next digit
  385. X    subi.b    #'0',d2                 ;Ascii adjust
  386. X    cmpi.b    #' ',(a2)               ;Hit end of report?
  387. X     beq.s    2$            ;Yep
  388. X    mulu    #$000a,d2        ;Else shift by 10
  389. X    add.b    (a2),d2                 ;Add next digit
  390. X    subi.b    #'0',d2                 ;Ascii adjust
  391. X
  392. X2$
  393. Xgwbupdate:
  394. X* Finally, update parameters by reference
  395. X    movea.l height(a5),a0           ;Grab height VPARM
  396. X    move.l    d1,(a0)                 ;*height = d1
  397. X    movea.l width(a5),a0            ;Grab width VPARM
  398. X    move.l    d2,(a0)                 ;*width = d2
  399. X
  400. Xgwbdone:
  401. X    movem.l (sp)+,d2-d4/a2/a6
  402. X    unlk    a5
  403. X    rts
  404. X
  405. X* --------------------------------------------------------------------- *
  406. X* void __asm SetConsoleType(flag, id, packet, port)
  407. X*   register __d0 long flag;
  408. X*   register __a0 struct Process *id;
  409. X*   register __a1 struct StandardPacket *packet;
  410. X*   register __a2 struct MsgPort *port;
  411. X*
  412. X* Flag = 1L -- Raw mode
  413. X*      = 0L -- Cooked mode
  414. X* --------------------------------------------------------------------- *
  415. X    XDEF    SetConsoleType
  416. XSetConsoleType:
  417. X    movem.l a2/a3/a5/a6,-(sp)
  418. X
  419. X    movea.l a0,a3            ;Copy process pointer
  420. X    movea.l a1,a5            ;Copy packet pointer
  421. X    lea    sp_Pkt(a5),a0           ;a0 = &packet->sp_Pkt
  422. X    move.l    a0,sp_Msg+LN_NAME(a5)   ;p->sp_Msg.mn_Node.ln_Name = &p->sp_Pkt
  423. X    lea    sp_Msg(a5),a0           ;a0 = &packet->sp_Msg
  424. X    move.l    a0,sp_Pkt+dp_Link(a5)   ;p->sp_Pkt.dp_Link = &p->sp_Msg
  425. X    move.l    a2,sp_Pkt+dp_Port(a5)   ;p->sp_Pkt.dp_Port = replyport
  426. X    move.l    #ACTION_SCREEN_MODE,sp_Pkt+dp_Type(a5)  ;Set function
  427. X
  428. X    tst.w    d0            ;On or Off?
  429. X     beq    1$
  430. X    move.l    #-1,sp_Pkt+dp_Arg1(a5)  ;RAW ON
  431. X    bra.s    2$
  432. X1$
  433. X    clr.l    sp_Pkt+dp_Arg1(a5)      ;RAW OFF
  434. X2$
  435. X    movea.l a3,a0
  436. X    movea.l a5,a1
  437. X    SYS    PutMsg,4        ;PutMsg(proc, packet)
  438. X
  439. X    movea.l a2,a0
  440. X    SYS    WaitPort        ;WaitPort(port)
  441. X    movea.l a2,a0
  442. X    SYS    GetMsg            ;(void)GetMsg(port)
  443. X
  444. X    movem.l (sp)+,a2/a3/a5/a6
  445. X    rts
  446. X
  447. X* ------------------------------------------------------------------------- *
  448. X* struct MsgPort *CreatePort(name, pri) (a0/d0)
  449. X* ------------------------------------------------------------------------- *
  450. X    XDEF    CreatePort
  451. XCreatePort:
  452. X    movem.l d5/d7/a2/a5/a6,-(sp)
  453. X
  454. X    move.l    a0,a5            ;Save Name
  455. X    move.l    d0,d5            ;Save Pri
  456. X
  457. X* Allocate a free signal, crap out if we can't
  458. X    moveq    #-1,d0
  459. X    SYS    AllocSignal,4
  460. X    cmp.l    #-1,d0            ;Did we get a signal?
  461. X     bne.s    cpgotsig        ;Yep
  462. X    moveq    #0,d0            ;Otherwise return NULL
  463. X    bra    cpdone
  464. X
  465. Xcpgotsig:
  466. X    move.l    d0,d7            ;Save our signal
  467. X
  468. X* Allocate memory for MsgPort
  469. X    moveq    #MP_SIZE,d0        ;Size of MsgPort
  470. X    jsr    @myalloc        ;Allocate it
  471. X    tst.l    d0            ;Did we get it?
  472. X     bne.s    cpgotport        ;Yep
  473. X
  474. X    move.l    d7,d0            ;Otherwise crap out, free signal
  475. X    SYS    FreeSignal
  476. X    moveq    #0,d0            ;Return NULL
  477. X    bra    cpdone
  478. X
  479. Xcpgotport:
  480. X    move.l    d0,a2            ;This is our new port!
  481. X    move.l    a5,LN_NAME(a2)          ;port->mp_Node.ln_Name = name
  482. X    move.b    d5,LN_PRI(a2)           ;port->mp_Node.ln_Pri = priority
  483. X    move.b    #NT_MSGPORT,LN_TYPE(a2) ;port->mp_Node.ln_Type = NT_MSGPORT
  484. X    move.b    #PA_SIGNAL,MP_FLAGS(a2) ;port->mp_Flags = PA_SIGNAL
  485. X    move.b    d7,MP_SIGBIT(a2)        ;port->mp_SIGBIT = sigBit
  486. X    suba.l    a1,a1
  487. X    SYS    FindTask
  488. X    move.l    d0,MP_SIGTASK(a2)       ;port->mp_SIGTASK = FindTask(0L)
  489. X
  490. X    cmpa.l    #0,a5            ;Is this a new name?
  491. X    beq.s    cpnoname        ;Nope, add it to the msg list
  492. X
  493. X    movea.l a2,a1
  494. X    SYS    AddPort         ;Otherwise add this port
  495. X    move.l    a2,d0            ;Return port pointer
  496. X    bra.s    cpdone
  497. X
  498. Xcpnoname:
  499. X* Initialized New List head
  500. X    lea    MP_MSGLIST(a2),a0       ;a0 = &port->mp_MsgList
  501. X    move.l    a0,(a0)                 ;list->lh_Head = list
  502. X    addq.l    #4,(a0)                 ;list->lh_Head += 4L
  503. X    clr.l    4(a0)                   ;list->lh_Tail = 0L
  504. X    move.l    a0,8(a0)                ;list->lh_TailPred = list
  505. X    move.l    a2,d0            ;Return port pointer
  506. X
  507. Xcpdone:
  508. X    movem.l (sp)+,d5/d7/a2/a5/a6
  509. X    rts
  510. X
  511. X* ------------------------------------------------------------------------- *
  512. X* DeletePort(port)(d0)
  513. X* ------------------------------------------------------------------------- *
  514. X    XDEF    DeletePort
  515. XDeletePort:
  516. X    movem.l a5/a6,-(sp)
  517. X
  518. X    move.l    d0,a5
  519. X    movea.l $4,a6
  520. X    tst.l    LN_NAME(a5)             ;Is there a name?
  521. X    beq.s    dpnoname
  522. X
  523. X    move.l    d0,a1
  524. X    SYS    RemPort         ;RemPort(port)
  525. X
  526. Xdpnoname:
  527. X    move.b    #$ff,LN_TYPE(a5)        ;port->mp_Node.ln_Type = 0xff
  528. X    move.l    #-1,MP_MSGLIST(a5)      ;port->mp_MsgList.lh_Head = -1L
  529. X
  530. X    moveq    #0,d0
  531. X    move.b    MP_SIGBIT(a5),d0        ;d0 = port->mp_SigBit
  532. X    SYS    FreeSignal        ;FreeSignal(d0)
  533. X
  534. X    movea.l a5,a0
  535. X    jsr    @myfree         ;FreeBlock(port)
  536. X
  537. X    movem.l (sp)+,a5/a6
  538. X    rts
  539. X
  540. X* ------------------------------------------------------------------------
  541. X* FibFileDate(fib_date, datestr, timestr)
  542. X*        a0      a1       8(a5)
  543. X*   struct DateStamp *fib_date;
  544. X*   char *datestr, *timestr;
  545. X*   Calculate date based on DateStamp structure and return a pointer
  546. X* to the formatted date string.
  547. X* ------------------------------------------------------------------------
  548. X    XDEF    @FibFileDate
  549. X@FibFileDate:
  550. X    link    a5,#0
  551. X    movem.l d3-d7/a2-a3/a6,-(sp)
  552. X
  553. X    movea.l a1,a3            ;a3 = datestr, 8(a5) = timestr
  554. X    movea.l a0,a1            ;Grab datestamp pointer
  555. X    moveq    #78,d7            ;Initial year = 1978
  556. X
  557. X    move.l    (a1),d5                 ;days = fib_date->ds_Days
  558. X     blt    ffdbaddate        ;Hey! you can't be negative! Invalid date...
  559. X
  560. X* Determine what year it is
  561. X    divu    #1461,d5
  562. X    move.l    d5,d0            ;Stash it
  563. X    ext.l    d5
  564. X    lsl.l    #2,d5
  565. X    add.l    d5,d7            ;year += (days / 1461) * 4
  566. X
  567. X* Count how many months into that year
  568. Xffdgetmo:
  569. X    swap    d0            ;days %= 1461
  570. X    move.w    d0,d5
  571. X
  572. X1$    tst.w    d5            ;Out of days yet?
  573. X     beq.s    3$            ;Yep, done here
  574. X
  575. X    move.w    #365,d6         ;Else month_days = 365
  576. X    move.w    d7,d0            ;Grab year
  577. X    andi.w    #3,d0            ;if (year & 3) == 0 Leap year?
  578. X     bne.s    2$            ;Nope
  579. X    addq.w    #1,d6            ;Otherwise bump month_days
  580. X
  581. X2$    cmp.w    d6,d5            ;is day < month_days?
  582. X     blt.s    3$            ;yep, done here
  583. X    sub.w    d6,d5            ;otherwise day -= month_days
  584. X
  585. X    addq.l    #1,d7            ; year++
  586. X    bra    1$
  587. X3$
  588. X
  589. X* Count how many days into that month of that year
  590. Xffdgetday:
  591. X;for (i = 0, day++; i < 12; i++)
  592. X    moveq    #0,d4            ;current month = 0
  593. X    moveq    #0,d6            ;Zap hinybs
  594. X    addq.w    #1,d5
  595. X    lea    dayspermonth(a4),a0
  596. X
  597. X1$
  598. X    move.b    0(a0,d4.w),d6           ;month_days = dayspermonth[i]
  599. X
  600. X    cmpi.w    #1,d4            ;if (i == 1 && (year & 3) == 0)
  601. X     bne.s    2$
  602. X    move.w    d7,d0
  603. X    andi.w    #3,d0
  604. X     bne.s    2$
  605. X    addq.w    #1,d6            ;month_days++
  606. X
  607. X2$    cmp.w    d6,d5            ;if (day <= month_days)
  608. X     ble.s    4$            ;Break out, found the right month
  609. X
  610. X    sub.w    d6,d5            ;Else, day -= month_days
  611. X
  612. X    addq.w    #1,d4            ;i++
  613. X3$    cmpi.w    #12,d4            ;Done all months yet?
  614. X     blt    1$            ;Nope
  615. X
  616. X4$
  617. Xffdprint:
  618. X1$    cmpi.l    #99,d7            ;while (year >= 100)
  619. X     ble.s    2$
  620. X    subi.l    #100,d7         ;year -= 100
  621. X    bra    1$
  622. X2$
  623. X;asprintf(datestr, "%02d-%02d-%02d %02d:%02d:%02d", i + 1, day, year, hour, min, sec)
  624. X    move.l    8(a1),d0                ;sec = fib_date->ds_Tick / 50;
  625. X    divu    #50,d0
  626. X    ext.l    d0
  627. X    move.l    d0,-(sp)                ;Push secs
  628. X    move.l    4(a1),d0                ;min = fib_date->ds_Minute
  629. X    move.l    d0,d1            ;Clone it
  630. X    divu    #60,d0
  631. X    moveq    #0,d3
  632. X    move.w    d0,d3            ;hour = min / 60
  633. X    mulu    #60,d0
  634. X    sub.w    d0,d1            ;min -= hour * 60
  635. X    move.l    d1,-(sp)                ;Push mins
  636. X    move.l    d3,-(sp)                ;Push hours
  637. X    pea    timepat(a4)             ;Push the format pattern
  638. X    move.l    8(a5),-(sp)             ;Push destination buffer, datestr
  639. X    jsr    asprintf
  640. X    lea    20(sp),sp
  641. X
  642. X    move.l    d5,-(sp)                ;Push day
  643. X    addq.w    #1,d4            ;Push month (offset by 1!)
  644. X    move.l    d4,-(sp)
  645. X    move.l    d7,-(sp)                ;Push year
  646. X    pea    datepat(a4)             ;Push the format pattern
  647. X    move.l    a3,-(sp)                ;Push destination buffer
  648. X    jsr    asprintf
  649. X    lea    20(sp),sp
  650. X
  651. Xffddone:
  652. X    movem.l (sp)+,d3-d7/a2-a3/a6
  653. X    unlk    a5
  654. X    rts
  655. X
  656. Xffdbaddate:
  657. X    lea    badtimestr(a4),a1       ;stpcpy (timestr, "00:00:00");
  658. X    movea.l 8(a5),a0
  659. X    jsr    @stpcpy
  660. X    lea    baddatestr(a4),a1       ;stpcpy (datestr, "00-00-00");
  661. X    movea.l a3,a0
  662. X    jsr    @stpcpy
  663. X    bra    ffddone
  664. X
  665. X*----------------------------------------------------------------------
  666. X* LONG iswild(name)
  667. X*   char *name;
  668. X*       a0
  669. X* Search a string for wild characters, return 1 if found
  670. X*----------------------------------------------------------------------
  671. X    XDEF    @iswild
  672. X@iswild:
  673. X    moveq    #0,d0            ;Clear out our character register
  674. Xischk1:
  675. X    move.b    (a0)+,d0                ;Grab a char
  676. X     beq.s    iwdone            ;Might be end of string?
  677. X    cmpi.b    #'*',d0                 ;Is it *?
  678. X     beq.s    iswdone         ;yep, is wild
  679. X    cmpi.b    #'?',d0                 ;Is it a qmark
  680. X     bne.s    ischk1            ;Nope, check next character
  681. X
  682. Xiswdone:
  683. X    moveq    #1,d0
  684. Xiwdone:
  685. X    rts
  686. X
  687. X* ------------------------------------------------------------------------
  688. X; Compare a wild card name with a normal name
  689. X; LONG wildmatch (name, wild)
  690. X;   char *name, *wild;
  691. X;       a0      a1
  692. X* ------------------------------------------------------------------------
  693. X    XDEF    @wildmatch
  694. X@wildmatch:
  695. X    link    a5,#-64
  696. X    movem.l d2-d3/a2-a3,-(sp)
  697. X
  698. X    move.l    LSFlags(a4),d2          ;Grab flags
  699. X    movea.l a0,a2            ;Grab name
  700. X    movea.l a1,a3            ;Grab pattern
  701. X    lea    -64(a5),a0              ;back[0][0]
  702. X    lea    -60(a5),a1              ;back[0][1]
  703. X
  704. X    moveq    #0,d3            ;bi = 0
  705. X
  706. Xwmloop1:
  707. X    tst.b    (a2)                    ;End of name?
  708. X    bne.s    wmnoteon
  709. X    tst.b    (a3)                    ;End of pattern?
  710. X    beq    wmmatched        ;Yep, we matched
  711. X
  712. Xwmnoteon:
  713. X    cmpi.b    #'*',(a3)               ;Is it a splat?
  714. X    bne.s    wmnotstar        ;Nope, maybe '?'
  715. X
  716. X    cmpi.w    #64,d3            ;Have we hit max expression depth?
  717. X    beq    wmnomatch        ;Yep, ran out of room in recursion table
  718. X
  719. X;back[bi][0] = w
  720. X    move.l    a3,0(a0,d3.w)           ;Stash pointer to this '*' in table
  721. X
  722. X;back[bi][1] = n
  723. X    move.l    a2,0(a1,d3.w)
  724. X
  725. X    addq.w    #8,d3            ;++bi
  726. X    addq.w    #1,a3            ;++w
  727. X    bra.s    wmloop1         ;Check next
  728. X
  729. Xwmgoback:
  730. X    subq.w    #8,d3            ;--bi
  731. X    move.l    a0,d0
  732. Xwmback1:
  733. X    tst.w    d3            ;while (bi >= 0 && *back[bi][1] == '\x0')
  734. X    blt.s    wmbacked
  735. X    movea.l 0(a1,d3.l),a0
  736. X    tst.b    (a0)
  737. X    bne.s    wmbacked
  738. X
  739. X    subq.w    #8,d3            ;--bi
  740. X    bra.s    wmback1
  741. X
  742. Xwmbacked:
  743. X    tst.w    d3            ;if (bi < 0)
  744. X    blt.s    wmnomatch        ;return (0)
  745. X
  746. X    movea.l d0,a0
  747. X    movea.l 0(a0,d3.w),a3           ;w = back[bi][0] + 1
  748. X    addq.w    #1,a3
  749. X
  750. X    addq.l    #1,0(a1,d3.w)
  751. X    movea.l 0(a1,d3.l),a2           ;n = ++back[bi][1]
  752. X
  753. X    addq.w    #8,d3            ;++bi
  754. X    bra.s    wmloop1
  755. X
  756. Xwmnotstar:
  757. X    cmpi.b    #'?',(a3)               ;Is it '?'
  758. X    bne.s    wmnotqmark
  759. X
  760. X    tst.b    (a2)                    ;Reached end of string?
  761. X    bne.s    wmincpoint        ;Nope, move on to next char
  762. X
  763. X    tst.w    d3            ;Are we at top level of expression?
  764. X    beq.s    wmnomatch        ;Yep, expression didn't match
  765. X    bra.s    wmgoback        ;Otherwise pop a level and try to match
  766. X
  767. Xwmnotqmark:
  768. X    move.b    (a2),d0                 ;Grab a char from bstr
  769. X    move.b    (a3),d1                 ;Grab a char from astr
  770. X    btst.l    #21,d2            ;LSFlags & IGNORECASEWILD?
  771. X    beq.s    2$            ;Nope, blow off lowercasing crap
  772. X
  773. X    cmpi.b    #$40,d0         ;less than @ character?  (for bstr)
  774. X    bls.s    1$            ;Yep
  775. X    cmpi.b    #$5a,d0         ;Greater than Z?
  776. X    bhi.s    1$            ;Yep
  777. X    addi.b    #$20,d0
  778. X1$
  779. X    cmpi.b    #$40,d1         ;less than @ character?  (for astr)
  780. X    bls.s    2$            ;Yep
  781. X    cmpi.b    #$5a,d1         ;Greater than Z?
  782. X    bhi.s    2$            ;Yep
  783. X    addi.b    #$20,d1
  784. X2$
  785. X    cmp.b    d0,d1            ;*n = *w?
  786. X    beq.s    wmincpoint        ;Yep, move on past
  787. X
  788. X    tst.w    d3            ;Are we at top expression level?
  789. X    beq.s    wmnomatch        ;Yep, they didn't match
  790. X    bra.s    wmgoback        ;Nope, process next part
  791. X
  792. Xwmincpoint:
  793. X    tst.b    (a2)                    ;Done with name?
  794. X    beq.s    wmnamend        ;Yep
  795. X    addq.w    #1,a2            ;Otherwise increment name pointer
  796. X
  797. Xwmnamend:
  798. X    tst.b    (a3)                    ;End of pattern?
  799. X    beq.s    wmmatched        ;Yep, we matched
  800. X    addq.w    #1,a3            ;Otherwise inc wild pointer, match next char
  801. X    bra    wmloop1
  802. X
  803. Xwmmatched:
  804. X    moveq    #1,d0
  805. X    bra.s    wmdone
  806. X
  807. Xwmnomatch:
  808. X    moveq    #0,d0
  809. X
  810. Xwmdone:
  811. X    movem.l (sp)+,d2-d3/a2-a3
  812. X    unlk    a5
  813. X    rts
  814. X
  815. X* --------------------------------------------------------------------- *
  816. X* BOOL CompFibs (keytype, a,   b)
  817. X*            d0     a0   a1
  818. X*   LONG keytype;
  819. X*   struct FileInfoBlock *a, *b;
  820. X*
  821. X* Used by SortFibs to determine precedence of Fibs.
  822. X* keytype is one of 0, 1, 2, or 3:
  823. X*   0=alpha, 1=size, 2=date, 3=diskkey
  824. X* --------------------------------------------------------------------- *
  825. X    XDEF    @CompFibs
  826. X@CompFibs:
  827. X    movem.l d2-d3/a2,-(sp)
  828. X
  829. X    move.l    d0,d2            ;Stash keytype
  830. X
  831. X* Prioritize Dirs/Files?
  832. X    move.l    LSFlags(a4),d3          ;Grab flags
  833. X
  834. X    btst.l    #17,d3            ;LSFlags & SEPFILESDIRS?
  835. X    beq.s    cftstsort        ;No, don't bother comparing EntryTypes
  836. X
  837. X    move.l    fib_DirEntryType(a0),d0
  838. X    cmp.l    fib_DirEntryType(a1),d0
  839. X    blt.s    1$            ;a0 is < a1, (dir < file)
  840. X    beq.s    cftstsort        ;a0 is == a1, try next test
  841. X
  842. X    moveq    #0,d0            ;a0 is > a1, (file > dir)
  843. X    bra.s    2$
  844. X1$
  845. X    moveq    #1,d0            ;greater than, (dir < file)
  846. X
  847. X2$    btst.l    #16,d3            ;LSFlags & FILESFIRST?
  848. X    beq    cfexit0         ;Nope, default Dirs first
  849. X    bchg.l    #0,d0            ;Else d0 ^= 1, reverse sense
  850. X    bra    cfexit0
  851. X
  852. X* Both entries are the same type, now see about sorting them
  853. Xcftstsort:
  854. X    btst.l    #6,d3            ;LSFlags & NOSORTFLAG set?
  855. X    bne    cffalse         ;Yep, always AddTail to list
  856. X
  857. X* Switch keytype
  858. X    tst.w    d2            ;Alphabetize?
  859. X    bne.s    cfnalpha        ;Nope
  860. X
  861. X* Compare lexigraphically, optionally ignoring case differences
  862. Xcfalpha:
  863. X    lea    fib_FileName(a0),a0     ;a = &Fipb->fib_FileName
  864. X    lea    fib_FileName(a1),a1     ;b = &Fipb->fib_FileName
  865. X
  866. X; for(; *a && tolower(*a) == tolower(*b); a++, b++); [tolower() crap optional]
  867. Xlccstart:
  868. X    tst.b    (a0)                    ;Is there a char here at source?
  869. X    beq.s    lcceostr        ;Nope, fell off the end
  870. X
  871. X    move.b    (a1)+,d1                ;Grab a char from bstr
  872. X    move.b    (a0)+,d0                ;Grab a char from astr
  873. X    btst.l    #20,d3            ;LSFlags & IGNORECASELIST?
  874. X    beq.s    2$            ;Nope, blow off lowercasing crap
  875. X
  876. X    cmpi.b    #$40,d1         ;less than @ character?  (for bstr)
  877. X    bls.s    1$            ;Yep
  878. X    cmpi.b    #$5a,d1         ;Greater than Z?
  879. X    bhi.s    1$            ;Yep
  880. X    addi.b    #$20,d1
  881. X1$
  882. X    cmpi.b    #$40,d0         ;less than @ character?  (for astr)
  883. X    bls.s    2$            ;Yep
  884. X    cmpi.b    #$5a,d0         ;Greater than Z?
  885. X    bhi.s    2$            ;Yep
  886. X    addi.b    #$20,d0
  887. X2$
  888. X    cmp.b    d0,d1            ;are they the same?
  889. X    beq.s    lccstart        ;Yep, compare next pair of chars
  890. X
  891. Xlcceostr:
  892. X    sub.b    d1,d0            ;return([tolower](*astr) - [tolower](*bstr))
  893. X    bgt.s    cftrue            ; > 0?, return TRUE
  894. X    bra.s    cffalse         ;Else return FALSE
  895. X
  896. Xcfnalpha:
  897. X    subq.w    #1,d2            ;Size?
  898. X    bne.s    cfnsize         ;Nope
  899. X
  900. X* Compare fib_Sizes
  901. X    move.l    fib_Size(a0),d0         ;d0 = afib->fib_Size
  902. X    cmp.l    fib_Size(a1),d0         ;b->fib_Size < a->fib_Size?
  903. X    blt.s    cftrue            ;Yep, return TRUE
  904. X    bgt.s    cffalse         ;>, return FALSE
  905. X    bra.s    cfalpha         ;Else it's a tie, alphabetize
  906. X
  907. Xcfnsize:
  908. X    subq.w    #1,d2            ;Date?
  909. X    bne.s    cfndate         ;No
  910. X
  911. X* Compare fib_DateStamps
  912. X    lea    fib_DateStamp(a0),a0    ;a = &afib->fib_DateStamp
  913. X    lea    fib_DateStamp(a1),a1    ;b = &bfib->fib_DateStamp
  914. X    jsr    @CompareDateStamps
  915. X    tst.l    d0
  916. X    blt.s    cftrue
  917. X    bgt.s    cffalse
  918. X    bra.s    cfalpha         ;same date; alphabetize
  919. X
  920. Xcfndate:
  921. X*Compare fib_DiskKeys
  922. X    move.l    fib_DiskKey(a0),d0      ;d0 = afib->fib_DiskKey
  923. X    cmp.l    fib_DiskKey(a1),d0      ;b->fib_DiskKey < a->fib_DiskKey?
  924. X    beq.s    cfalpha         ;shouldn't happen [bad filesys if so]
  925. X    blt.s    cffalse         ;<, return FALSE
  926. X
  927. Xcftrue:
  928. X    moveq    #1,d0
  929. X    bra.s    cfexit
  930. Xcffalse:
  931. X    moveq    #0,d0
  932. Xcfexit:
  933. X    btst.l    #9,d3            ;LSFlags & REVFLAG?
  934. X    beq.s    1$            ;Nope
  935. X    bchg.l    #0,d0            ;Else invert boolean result
  936. X1$
  937. Xcfexit0:
  938. X    movem.l (sp)+,d2-d3/a2
  939. X    rts
  940. X
  941. X* --------------------------------------------------------------------- *
  942. X* LONG CompareDateStamps(adate, bdate)
  943. X*  d0              a0      a1
  944. X*   struct DateStamp *adate, *bdate;
  945. X* --------------------------------------------------------------------- *
  946. X    XDEF    @CompareDateStamps
  947. X@CompareDateStamps:
  948. X    move.l    ds_Days(a0),d0          ;d0 = adate->ds_Days
  949. X    sub.l    ds_Days(a1),d0          ;b->ds_Days > a->ds_Days?
  950. X    bne.s    1$            ;Return b->day - a->day
  951. X
  952. X;They are the same day, check min/tick
  953. X    move.l    ds_Minute(a0),d0
  954. X    sub.l    ds_Minute(a1),d0        ;d0 = amin - bmin
  955. X    muls    #3000,d0        ;     * 3000
  956. X    add.l    ds_Tick(a0),d0
  957. X    sub.l    ds_Tick(a1),d0          ;     + atick - btick
  958. X1$
  959. X    rts
  960. X
  961. X* --------------------------------------------------------------------- *
  962. X* VOID InsertFibNode(hfib, newfib)
  963. X*              a0     a1
  964. X*   struct List *hfib;
  965. X*   struct FibEntry *newfib;
  966. X*
  967. X* Compare data in newfib->Fib with nodes in the list until we
  968. X* find the insertion point.
  969. X* --------------------------------------------------------------------- *
  970. X    XDEF    @InsertFibNode
  971. X@InsertFibNode:
  972. X    movem.l d2/a2-a3/a5/a6,-(sp)
  973. X
  974. X    move.l    sortkey(a4),d2
  975. X    movea.l a0,a3            ;a3 = hfib
  976. X    movea.l a1,a2            ;a2 = newfib
  977. X
  978. X    movea.l LH_HEAD(a3),a5          ;afib = hfib->lh_Head
  979. X
  980. X1$    tst.l    fe_Node+LN_SUCC(a5)     ;afib->fe_Node.mln_Succ != 0?
  981. X    beq.s    4$
  982. X
  983. X    movea.l fe_Fib(a2),a1
  984. X    movea.l fe_Fib(a5),a0
  985. X    move.l    d2,d0
  986. X    jsr    @CompFibs        ;CompFibs(sortkey, afib->Fib, newfib->Fib)
  987. X    tst.w    d0
  988. X    bne.s    4$
  989. X    movea.l fe_Node+LN_SUCC(a5),a5  ;afib = afib->fe_Node.mln_Succ
  990. X    bra    1$
  991. X
  992. X4$    movea.l a3,a0            ;a0 = List *
  993. X    movea.l a2,a1            ;a1 = Node *
  994. X    movea.l fe_Node+LN_PRED(a5),a2  ;a2 = Pred *
  995. X    SYS    Insert,4        ;Insert(hfib, newfib, afib->fe_Node.mln_Succ)
  996. X
  997. X    movem.l (sp)+,d2/a2-a3/a5/a6
  998. X    rts
  999. X
  1000. X* --------------------------------------------------------------------- *
  1001. X* LONG FillFibEntry (headfib, fibp)
  1002. X*               a0      a1
  1003. X*   struct List *headfib;
  1004. X*   struct FileInfoBlock *fibp;
  1005. X* --------------------------------------------------------------------- *
  1006. X    XDEF    @FillFibEntry
  1007. X@FillFibEntry:
  1008. X    movem.l a2-a3/a5/a6,-(sp)
  1009. X    movea.l a0,a2            ;a2 = head of list
  1010. X    movea.l a1,a3            ;a3 = fileinfoblock
  1011. X
  1012. X    jsr    @AllocFib        ;Allocate a new fib
  1013. X    tst.l    d0            ;Got it?
  1014. X    beq.s    3$            ;Nope, return 0
  1015. X    movea.l d0,a5            ;a5 = tfibp = AllocFib()
  1016. X
  1017. X    move.l    #fib_SIZEOF,d0
  1018. X    movea.l fe_Fib(a5),a1
  1019. X    movea.l a3,a0
  1020. X    SYS    CopyMem,4        ;CopyMem(fibp, tfibp->Fib, sizeof(struct fib))
  1021. X
  1022. X    movea.l a5,a1
  1023. X    movea.l a2,a0
  1024. X
  1025. X    jsr    @InsertFibNode        ;InsertFibNode(headfib, tfibp)
  1026. X
  1027. X    moveq    #1,d0            ;return(1)
  1028. X3$
  1029. X    movem.l (sp)+,a2-a3/a5/a6
  1030. X    rts
  1031. X
  1032. X* --------------------------------------------------------------------- *
  1033. X    XDEF    @nullstub
  1034. X@nullstub:
  1035. X    moveq    #0,d0
  1036. X    rts
  1037. X
  1038. X* --------------------------------------------------------------------- *
  1039. X* LONG GetPathString (dest, src)
  1040. X*  d0               a0    a1
  1041. X*   BYTE *dest, *src;
  1042. X* --------------------------------------------------------------------- *
  1043. X    XDEF    @GetPathString
  1044. X@GetPathString:
  1045. X    move.l    a2,-(sp)
  1046. X
  1047. X    moveq    #0,d0            ;Zero return dest length
  1048. X
  1049. X* Find end of src string
  1050. X    movea.l a1,a2            ;Save src start address
  1051. X1$    tst.b    (a1)+                   ;while (*src++ != 0)
  1052. X    bne.s    1$
  1053. X
  1054. X* Work backwards till we find a ':' or a '/'
  1055. X2$    move.b    -(a1),d1                ;c = *(--src)
  1056. X    cmpi.b    #':',d1                 ;Hit a colon?
  1057. X    beq.s    4$            ;Yep, found our path end
  1058. X    cmpi.b    #'/',d1                 ;Hit a slash?
  1059. X    bne.s    3$            ;Nope, try next char
  1060. X    cmpa.l    a2,a1            ;At first char?
  1061. X    beq.s    4$            ;Yep, leave the single slash
  1062. X    cmpi.b    #'/',-1(a1)             ;Next char back is also a '/'?
  1063. X    beq.s    4$            ;Yep, allow multiple slashes
  1064. X    subq.w    #1,a1            ;Else backup to previous char, eliminate '/'
  1065. X    bra.s    4$
  1066. X3$
  1067. X    cmpa.l    a2,a1            ;Back at start of src?
  1068. X    bhi.s    2$            ;Nope, try previous src char
  1069. X    bra.s    gpsdone         ;Else no dest, return
  1070. X4$
  1071. X* Copy path portion to dest
  1072. Xgpscpy:
  1073. X    cmpa.l    a2,a1            ;Past end address?
  1074. X    bcs.s    gpsdone         ;Yep, terminate
  1075. X    move.b    (a2)+,(a0)+             ;Copy a char from src to dest
  1076. X    addq.w    #1,d0            ;Bump dest length count
  1077. X    bra.s    gpscpy            ;Check end address
  1078. Xgpsdone:
  1079. X    clr.b    (a0)                    ;Null terminate dest
  1080. X
  1081. X    movea.l (sp)+,a2
  1082. X    rts
  1083. X
  1084. X* --------------------------------------------------------------------- *
  1085. X* LONG GetFileString (dest, src)
  1086. X*  d0               a0    a1
  1087. X*   BYTE *dest, *src;
  1088. X* --------------------------------------------------------------------- *
  1089. X    XDEF    @GetFileString
  1090. X@GetFileString:
  1091. X    move.l    a2,-(sp)
  1092. X
  1093. X    moveq    #0,d0            ;Zero return dest length
  1094. X
  1095. X* Find end of src string
  1096. X    movea.l a1,a2            ;Save src start address
  1097. X1$    tst.b    (a1)+                   ;while (*src++ != 0)
  1098. X    bne.s    1$
  1099. X
  1100. X* Work backwards till we find a ':' or a '/'
  1101. X2$    move.b    -(a1),d1                ;c = *(--src)
  1102. X    cmpi.b    #':',d1                 ;Hit a colon?
  1103. X    beq.s    4$            ;Yep, found our path end
  1104. X    cmpi.b    #'/',d1                 ;Hit a slash?
  1105. X    beq.s    4$            ;Nope, try next char
  1106. X3$
  1107. X    cmpa.l    a2,a1            ;Back at start of src?
  1108. X    bhi.s    2$            ;Nope, try previous src char
  1109. X    bra.s    gfscpy            ;Else no path, entire src is filename
  1110. X4$
  1111. X    addq.w    #1,a1            ;Move past ':' or '/'
  1112. X
  1113. X* Copy name portion to dest
  1114. Xgfscpy:
  1115. X    move.b    (a1)+,(a0)+             ;Copy a char from src to dest
  1116. X    beq.s    2$
  1117. X    addq.w    #1,d0            ;Bump dest length count
  1118. X    bra.s    gfscpy            ;Check end address
  1119. X2$
  1120. X    movea.l (sp)+,a2
  1121. X    rts
  1122. X
  1123. X* ------------------------------------------------------------------------- *
  1124. X* BYTE *astrncpy(dst, src, len)
  1125. X* d0/a0      a0   a1    d0
  1126. X* Takes text in a1, copies d0 bytes to text in a0.
  1127. X* a0 returns pointing to null at end of final text.
  1128. X* Dest text is always null terminated.
  1129. X* ------------------------------------------------------------------------- *
  1130. X    XDEF    @astrncpy
  1131. X@astrncpy:
  1132. X1$    subq.l    #1,d0            ;Dec count
  1133. X    blt.s    2$            ;Done!
  1134. X
  1135. X    move.b    (a1)+,(a0)+             ;Copy a byte
  1136. X    bne.s    1$            ;Do until end of src or cnt < 0
  1137. X2$
  1138. X    clr.b    (a0)                    ;Null terminate dest
  1139. X    move.l    a0,d0            ;Return in d0 also
  1140. X    rts
  1141. X
  1142. X* ------------------------------------------------------------------------- *
  1143. X* VOID amovmem(src, dst, len)
  1144. X*           a0    a1   d0
  1145. X* Takes text in a0, copies d0 bytes to text in a1. Correctly handles
  1146. X* overlapping memory.
  1147. X* ------------------------------------------------------------------------- *
  1148. X    XDEF    amovmem
  1149. Xamovmem:
  1150. X    cmpa.l    a0,a1            ;Low to high or high to low?
  1151. X     bcs.s    2$            ;High to low, copy forward
  1152. X    adda.w    d0,a0            ;Else start at end, copy backward
  1153. X    adda.w    d0,a1
  1154. X
  1155. X1$    move.b    -(a0),-(a1)
  1156. X    subq.w    #1,d0
  1157. X     bgt    1$
  1158. X    bra.s    amdone
  1159. X
  1160. X2$    move.b    (a0)+,(a1)+
  1161. X    subq.w    #1,d0
  1162. X     bgt    2$
  1163. Xamdone:
  1164. X    rts
  1165. X
  1166. X* --------------------------------------------------------------------- *
  1167. X* BYTE *aindex(BYTE *, BYTE);
  1168. X*  d0        a0    d0
  1169. X* --------------------------------------------------------------------- *
  1170. X    XDEF    @aindex
  1171. X@aindex:
  1172. X1$    cmp.b    (a0),d0
  1173. X     beq.s    aifound
  1174. X    tst.b    (a0)+
  1175. X     beq.s    ainomatch
  1176. X    bra    1$
  1177. X
  1178. Xainomatch:
  1179. X    moveq    #0,d0
  1180. X    rts
  1181. X
  1182. Xaifound:
  1183. X    move.l    a0,d0
  1184. X    rts
  1185. X
  1186. X* --------------------------------------------------------------------- *
  1187. X* LONG MakePathString(lock, dest)
  1188. X*               a0     a1
  1189. X*   struct FileLock *lock;
  1190. X*   BYTE *dest;
  1191. X*
  1192. X* DESCRIPTION:
  1193. X*   Given text and a filelock, construct entire pathname and
  1194. X* return in dest.
  1195. X* --------------------------------------------------------------------- *
  1196. X    XDEF    @MakePathString
  1197. X@MakePathString:
  1198. X    movem.l d2-d5/d7/a2-a3/a6,-(sp)
  1199. X
  1200. X* Grab pointer to lock and dest text to fill
  1201. X    move.l    a0,d3            ;d3 = lock
  1202. X    movea.l a1,a2            ;a2 = dest
  1203. X    clr.b    (a2)                    ;NULL terminate dest
  1204. X    moveq    #0,d5            ;LockFlag = 0
  1205. X
  1206. X* Allocate a FileInfoBlock for local use
  1207. X    move.l    #fib_SIZEOF,d0
  1208. X    jsr    @myalloc
  1209. X    move.l    d0,d7            ;d7 = *fib
  1210. X     beq    mpsfailed        ;Whoops no mem? return!
  1211. X
  1212. X    movea.l DOSBase(a4),a6          ;DOSBase calls from here on
  1213. X
  1214. X* while (lock != 0)
  1215. X1$
  1216. X    tst.l    d3            ;Got a lock?
  1217. X     beq.s    mpsokay         ;Nope, must be at root
  1218. X
  1219. X* Examine the current lock
  1220. X    move.l    d3,d1
  1221. X    move.l    d7,d2
  1222. X    SYS    Examine         ;Examine(lock, fib)
  1223. X    tst.l    d0            ;Okay?
  1224. X     beq.s    mpsfailed        ;Nope, some sort of dos failure?
  1225. X
  1226. X    movea.l d7,a1
  1227. X    cmpi.b    #' ',fib_FileName(a1)   ;if (fib->fib_FileName[0] >= ' ')
  1228. X     bcs.s    3$            ;Nope, don't bother inserting?
  1229. X
  1230. X    tst.b    (a2)                    ;if (dest[0] != 0)
  1231. X     beq.s    2$
  1232. X    lea    SlashStr(a4),a1
  1233. X    movea.l a2,a0
  1234. X    jsr    @InsertPathString    ;InsertPathString(dest, "/");
  1235. X2$
  1236. X    movea.l d7,a1
  1237. X    lea    fib_FileName(a1),a1
  1238. X    movea.l a2,a0
  1239. X    jsr    @InsertPathString    ;InsertPathString(dest, fib->fib_FileName)
  1240. X3$
  1241. X* Okay, move up one directory
  1242. X    move.l    d3,d4            ;oldlock = lock
  1243. X
  1244. X    move.l    d3,d1
  1245. X    SYS    ParentDir
  1246. X    move.l    d0,d3            ;lock = ParentDir(lock)
  1247. X
  1248. X    tst.w    d5            ;LockFlag set?
  1249. X     bne.s    4$            ;Yep, unlock
  1250. X    moveq    #1,d5            ;Else LockFlag = 1, unlock next time
  1251. X     bra    1$            ;Next directory up
  1252. X4$
  1253. X    move.l    d4,d1
  1254. X    SYS    UnLock            ;UnLock(oldlock)
  1255. X    bra    1$            ;Examine
  1256. X
  1257. Xmpsokay:
  1258. X* See if root was RAM:, special case
  1259. X    movea.l d7,a1            ;a1 = fib
  1260. X    cmpi.b    #' ',fib_FileName(a1)   ;if (fib->fib_FileName[0] >= ' ')
  1261. X     bcc.s    1$            ;Yep, not 1.1/1.2 RAM:
  1262. X    lea    RamNameStr(a4),a1       ;Else...
  1263. X    movea.l a2,a0
  1264. X    jsr    @InsertPathString    ;InsertPathString(dest, "RAM:")
  1265. X    bra.s    mpsdone
  1266. X1$
  1267. X* Find last slash we tacked on, change to a colon, or, add a colon
  1268. X    moveq    #'/',d0
  1269. X    movea.l a2,a0
  1270. X    jsr    @aindex         ;d0 = strchr(dest, '/')
  1271. X    tst.l    d0            ;Do we have a slash?
  1272. X     beq.s    2$            ;Nope, at root....
  1273. X    movea.l d0,a0
  1274. X    move.b    #':',(a0)               ;Else change first '/' to a ':'
  1275. X    bra.s    mpsdone
  1276. X
  1277. X* No slash, must be locked at the root.  Append a colon to the dest.
  1278. X2$
  1279. X    lea    ColonStr(a4),a1
  1280. X    movea.l a2,a0
  1281. X    jsr    @strcat         ;strcat (dest, ":")
  1282. X    bra.s    mpsdone
  1283. X
  1284. X* Come here if an error occured, return empty text to caller
  1285. Xmpsfailed:
  1286. X    clr.b    (a2)                    ;dest[0] = (BYTE)0
  1287. X    moveq    #0,d3            ;return (0L)
  1288. X    bra.s    mpsdeall
  1289. X
  1290. X* Come here if everything is okay, deallocate FileInfoBlock
  1291. Xmpsdone:
  1292. X    moveq    #1,d3            ;return (1L)
  1293. X
  1294. Xmpsdeall:
  1295. X    tst.l    d7            ;Did we allocate a fib?
  1296. X     beq.s    mpsfinis        ;nope
  1297. X    movea.l d7,a0            ;Else free the memory
  1298. X    jsr    @myfree
  1299. X
  1300. Xmpsfinis:
  1301. X    move.l    d3,d0            ;Put return value in d0
  1302. X    movem.l (sp)+,d2-d5/d7/a2-a3/a6
  1303. X    rts
  1304. X
  1305. X* --------------------------------------------------------------------- *
  1306. X* VOID InsertPathString(dest, source)
  1307. X*             a0    a1
  1308. X*   BYTE *dest, *source;
  1309. X*
  1310. X* DESCRIPTION:
  1311. X*   Insert source text into dest text.
  1312. X* Special case for source length == 0, source must be RAM.
  1313. X* --------------------------------------------------------------------- *
  1314. X    XDEF    @InsertPathString
  1315. X@InsertPathString:
  1316. X    movem.l d7/a2-a3,-(sp)
  1317. X
  1318. X    movea.l a1,a3            ;a3 = source
  1319. X    move.l    a0,a2            ;a2 = dest
  1320. X
  1321. X    movea.l a3,a0
  1322. X    jsr    @strlen
  1323. X    move.l    d0,d7            ;d7 = strlen(source)
  1324. X
  1325. X1$    movea.l a2,a0
  1326. X    jsr    @strlen         ;d0 = strlen(dest)
  1327. X
  1328. X    addq.w    #1,d0            ;Bump the length to include zero byte at end
  1329. X    movea.l a2,a1
  1330. X    adda.w    d7,a1            ;Push dest + slen
  1331. X    movea.l a2,a0            ;Push dest
  1332. X    jsr    amovmem         ;amovmem(dest, dest + slen, strlen(dest) + 1)
  1333. X
  1334. X    move.w    d7,d0
  1335. X    movea.l a2,a1
  1336. X    movea.l a3,a0
  1337. X    jsr    amovmem         ;amovmem(source, dest, slen)
  1338. X
  1339. X    movem.l (sp)+,d7/a2-a3
  1340. X    rts
  1341. X
  1342. X* --------------------------------------------------------------------- *
  1343. X    END
  1344. X* --------------------------------------------------------------------- *
  1345. END_OF_FILE
  1346. if test 34948 -ne `wc -c <'src/lssup.a'`; then
  1347.     echo shar: \"'src/lssup.a'\" unpacked with wrong size!
  1348. fi
  1349. # end of 'src/lssup.a'
  1350. fi
  1351. echo shar: End of archive 3 \(of 4\).
  1352. cp /dev/null ark3isdone
  1353. MISSING=""
  1354. for I in 1 2 3 4 ; do
  1355.     if test ! -f ark${I}isdone ; then
  1356.     MISSING="${MISSING} ${I}"
  1357.     fi
  1358. done
  1359. if test "${MISSING}" = "" ; then
  1360.     echo You have unpacked all 4 archives.
  1361.     rm -f ark[1-9]isdone
  1362. else
  1363.     echo You still need to unpack the following archives:
  1364.     echo "        " ${MISSING}
  1365. fi
  1366. ##  End of shell archive.
  1367. exit 0
  1368. -- 
  1369. Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
  1370. Mail comments to the moderator at <amiga-request@cs.odu.edu>.
  1371. Post requests for sources, and general discussion to comp.sys.amiga.
  1372.